package com.oazon.moco.lan.core.nsd;

import android.content.Context;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdManager.RegistrationListener;
import android.net.nsd.NsdServiceInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.util.Log;

import com.oazon.common.Assert;
import com.oazon.common.Settings;
import com.oazon.moco.link.core.LinkEventController;
import com.oazon.moco.link.core.LinkSDK;
import com.oazon.common.util.StringUtils;

public class NsdService {
	
	private static final String TAG = "NsdService";
	private static NsdService nsdService = null;
	private WifiLock wifiLock;
	private static Context context;
	private NsdManager mNsdManager;
	private int mPort;
	
	public static void init(Context context){
		NsdService.context = context;
	}
	
	private NsdService() {
		WifiManager wifiManager = (WifiManager) LinkSDK.getAppContext()
				.getSystemService(Context.WIFI_SERVICE);
		wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL,
				"JmDNS");
		wifiLock.acquire();
	}

	public synchronized static NsdService getInstance() {
		if (nsdService == null) {
			nsdService = new NsdService();
		}
		return nsdService;
	}
	
	public void registerService(int port, String serviceName) {
		Assert.isTrue(port > 1024, "NSDService Port invlaid");
		
		mPort = port;
		
		if (StringUtils.isEmpty(serviceName)) {
			if (!Settings.getInstance(context).get("nsd.serv.name", "").equals("")) 
				serviceName = Settings.getInstance(context).get("nsd.serv.name");
			else
				serviceName = LinkSDK.JMDNS_SERVICE_NAME;
		} else {
			Settings.getInstance(context).set("nsd.serv.name", serviceName);
		}

	    // Create the NsdServiceInfo object, and populate it.
	    NsdServiceInfo serviceInfo  = new NsdServiceInfo();

	    // The name is subject to change based on conflicts
	    // with other services advertised on the same network.
	    serviceInfo.setServiceName(serviceName + ":" + LinkSDK.UUID);
	    serviceInfo.setServiceType(NsdType.NSD_SERVICE_TYPE);
	    serviceInfo.setPort(port);
		
	    mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
	    mNsdManager.registerService(
	            serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener);
	}
	
	public void resetServiceName(String newName) {
		unRegisterService();
		registerService(mPort, newName);
	}
	
	public void unRegisterService(){
		mNsdManager.unregisterService(registrationListener);
	}
	
	RegistrationListener registrationListener = new RegistrationListener() {
		
		@Override
		public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
			Log.d(TAG, "onUnregistrationFailed"+serviceInfo.toString());
			LinkSDK.getInstance().closeServiceCallback(
					LinkEventController.lanSource, false);
		}
		
		@Override
		public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
			Log.d(TAG, "onServiceUnregistered"+serviceInfo.toString());
			LinkSDK.getInstance().closeServiceCallback(
					LinkEventController.lanSource, true);
		}
		
		@Override
		public void onServiceRegistered(NsdServiceInfo serviceInfo) {
			Log.d(TAG,"onServiceRegistered"+ serviceInfo.toString());
			LinkSDK.getInstance().openServiceCallback(
					LinkEventController.lanSource, true);
			
		}
		
		@Override
		public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
			Log.d(TAG, "onRegistrationFailed"+serviceInfo.toString());
			LinkSDK.getInstance().openServiceCallback(
					LinkEventController.lanSource, false);
		}
	};
}
